package com.bestcem.xm.txtanls.dao.impl.mysql;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.bestcem.xm.common.core.constant.Constants;
import com.bestcem.xm.common.core.uitls.DateUtil;
import com.bestcem.xm.txtanls.dao.RecordDao;
import com.bestcem.xm.txtanls.dao.dto.PageDTO;
import com.bestcem.xm.txtanls.dao.dto.RecordSentiDTO;
import com.bestcem.xm.txtanls.dao.mapper.TxtanlRecordMapper;
import com.bestcem.xm.txtanls.entity.mysql.PageRecordEntity;
import com.bestcem.xm.txtanls.entity.mysql.TxtanlRecordEntity;
import com.bestcem.xm.txtanls.entity.pojo.RecordDO;
import com.bestcem.xm.txtanls.grpc.service.param.PageParam;
import com.bestcem.xm.txtanls.service.dto.RecordSearchDTO;
import com.bestcem.xm.txtanls.service.dto.record.PageRecordDTO;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;

import static com.bestcem.xm.common.core.uitls.DateUtil.BEIJING_ZONE;

/**
 * 原话记录表DAO
 *
 * @author xa.zhang
 * @version v1.0
 * @date 2021/9/27-16:49
 */
@Repository
public class TxtanlRecordDaoImpl implements RecordDao {

    @Resource
    private TxtanlRecordMapper recordMapper;

    /**
     * 根据DTO参数查询原话记录Id
     *
     * @param recordSearchDTO 原话记录查询DTO
     * @return List<RecordEntity> 原话记录列表
     * @date 2021/10/13 13:55
     **/
    @Override
    public List<String> listRecordIds(RecordSearchDTO recordSearchDTO) {
        List<String> idList = recordMapper.listRecordIds(recordSearchDTO);
        if (idList == null) {
            return new ArrayList<>();
        }
        return idList;
    }

    /**
     * 统计原话记录数
     *
     * @param recordSearchDTO 查询条件
     * @return 原话记录数
     * @see RecordSearchDTO
     */
    @Override
    public Long countRecord(RecordSearchDTO recordSearchDTO) {
        Long count = recordMapper.countRecord(recordSearchDTO);
        if (count == null) {
            // 话题没有关键字，则直接返回0
            return 0L;
        }
        return count;
    }

    /**
     * 原话记录保存
     *
     * @param recordDO
     * @return
     */
    @Override
    public RecordDO insertRecord(RecordDO recordDO) {
        TxtanlRecordEntity recordEntity = doToEntity(recordDO);
        recordEntity.setRecordId(recordDO.getId());
        recordEntity.setCreateTime(DateUtil.getCommonDate());
        recordEntity.setUpdateTime(DateUtil.getCommonDate());

        recordMapper.insertSelective(recordEntity);

        recordDO.setId(recordEntity.getRecordId());
        recordDO.setCreatedDate(recordEntity.getCreateTime());
        recordDO.setUpdatedDate(recordEntity.getUpdateTime());
        return recordDO;
    }

    /**
     * entity转换成do
     *
     * @param entity 待转换实体
     * @return 转换后的结果
     */
    private RecordDO entityToDo(TxtanlRecordEntity entity) {
        RecordDO recordDo = new RecordDO();
        recordDo.setId(entity.getRecordId());
        recordDo.setCollectionId(entity.getCollectionId());

        recordDo.setContent(entity.getContent());
        recordDo.setProjectId(entity.getProjectId());
        recordDo.setFieldId(entity.getFieldId());
        recordDo.setFieldName(entity.getFieldName());
        recordDo.setIndustryId(entity.getIndustryId());
        recordDo.setSenti(entity.getSenti());
        recordDo.setSentiScore(entity.getSentiScore());
        recordDo.setSurveyId(entity.getSurveyId());
        recordDo.setWorkTableId(entity.getWorktableId());
        recordDo.setWorkName(entity.getWorktableName());

        recordDo.setCollectionTime(cn.hutool.core.date.DateUtil.format(entity.getCollectionTime(), "yyyy-MM-dd HH:mm:ss"));
        recordDo.setRecordTime(cn.hutool.core.date.DateUtil.format(entity.getRecordTime(), "yyyy-MM-dd HH:mm:ss"));
        recordDo.setCreatedDate(entity.getCreateTime());
        recordDo.setCreatedId(entity.getCreatorId());
        recordDo.setCreatedDate(entity.getCreateTime());
        recordDo.setUpdatedDate(entity.getUpdateTime());
        recordDo.setUpdatedId(entity.getOperatorId());
        recordDo.setSample(entity.getSample());

        return recordDo;
    }

    private List<RecordDO> listToDoList(List<TxtanlRecordEntity> entityList) {
        if (CollUtil.isEmpty(entityList)) {
            return Collections.emptyList();
        }
        ArrayList<RecordDO> recordDOS = new ArrayList<>(entityList.size());
        for (TxtanlRecordEntity txtanlRecordEntity : entityList) {
            recordDOS.add(entityToDo(txtanlRecordEntity));
        }
        return recordDOS;
    }

    private List<TxtanlRecordEntity> listDoToEntityList(List<RecordDO> doList) {
        if (CollUtil.isEmpty(doList)) {
            return Collections.emptyList();
        }
        ArrayList<TxtanlRecordEntity> recordEntities = new ArrayList<>(doList.size());
        for (RecordDO recordDO : doList) {
            recordEntities.add(doToEntity(recordDO));
        }
        return recordEntities;
    }

    /**
     * do转换成entity
     *
     * @param recordDO 待转换do
     * @return 转换后的结果
     */
    private TxtanlRecordEntity doToEntity(RecordDO recordDO) {
        TxtanlRecordEntity recordEntity = new TxtanlRecordEntity();
        recordEntity.setRecordId(recordDO.getId());
        recordEntity.setCollectionId(recordDO.getCollectionId());
        recordEntity.setContent(recordDO.getContent());
        recordEntity.setProjectId(recordDO.getProjectId());
        recordEntity.setFieldId(recordDO.getFieldId());
        recordEntity.setFieldName(recordDO.getFieldName());
        recordEntity.setIndustryId(recordDO.getIndustryId());
        recordEntity.setSenti(recordDO.getSenti());
        recordEntity.setSentiScore(recordDO.getSentiScore());
        recordEntity.setSurveyId(recordDO.getSurveyId());
        recordEntity.setWorktableId(recordDO.getWorkTableId());
        recordEntity.setWorktableName(recordDO.getWorkName());

        recordEntity.setCollectionTime(cn.hutool.core.date.DateUtil.parse(recordDO.getCollectionTime()));
        recordEntity.setRecordTime(cn.hutool.core.date.DateUtil.parse(recordDO.getRecordTime()));
        recordEntity.setCreatorId(recordDO.getCreatedId());
        recordEntity.setCreateTime(recordDO.getCreatedDate());
        recordEntity.setUpdateTime(recordDO.getUpdatedDate());
        recordEntity.setOperatorId(recordDO.getUpdatedId());
        recordEntity.setSample(recordDO.getSample());

        return recordEntity;
    }

    /**
     * 查询原话对应的情感，并对其结果进行聚合处理
     *
     * @param recordSearchDTO 原话查询参数
     * @return 结果
     */
    @Override
    public List<RecordSentiDTO> listRecordSentisGroupBySenti(RecordSearchDTO recordSearchDTO) {
        return recordMapper.listRecordSentisGroupBySenti(recordSearchDTO);

    }

    /**
     * 查询原话记录的内容
     *
     * @param recordSearchDTO 查询条件
     * @return 列表
     */
    @Override
    public List<String> listRecordContent(RecordSearchDTO recordSearchDTO) {
        List<String> list = recordMapper.listRecordContent(recordSearchDTO);
        if (list == null) {
            return new ArrayList<>();
        }
        return list;
    }

    /**
     * 根据关键词查询原话记录的Id
     *
     * @param recordSearchDTO 查询条件
     * @return 集合
     */
    @Override
    public Set<String> listRecordIdByKeywords(RecordSearchDTO recordSearchDTO) {
        List<String> list = recordMapper.listRecordIdByKeywords(recordSearchDTO);
        if (list == null) {
            return new HashSet<>();
        }
        return new HashSet<>(list);
    }

    /**
     * 根据关键词查询原话记录的数量
     *
     * @param recordSearchDTO
     * @return 数量
     */
    @Override
    public Long countRecordByKeyword(RecordSearchDTO recordSearchDTO) {
        Long count = recordMapper.countRecordByKeyword(recordSearchDTO);
        if (count == null) {
            return 0L;
        }
        return count;
    }

    /**
     * 根据项目id查找原话记录的最小时间
     *
     * @param projectId 项目id
     * @return 时间
     */
    @Override
    public LocalDateTime getMinRecordTimeByProject(String projectId) {
        Date date = recordMapper.getMinRecordTimeByProject(projectId);
        if (date == null) {
            return null;
        }
        return LocalDateTime.ofInstant(date.toInstant(), BEIJING_ZONE);
    }

    /**
     * 获取当前文本分析项目已有原话记录中的最大时间
     *
     * @param projectId projectId 项目id
     * @return 时间
     */
    @Override
    public LocalDateTime getMaxTime(String projectId) {
        Date date = recordMapper.getMaxTime(projectId);
        if (Objects.isNull(date)) {
            return null;
        }
        return DateUtil.toLocalTime(date);
    }

    /**
     * 分页查询原话记录
     *
     * @param pageRecordDTO 分页查询条件
     * @return 查询结果
     */
    @Override
    public PageDTO<RecordDO> pageRecord(PageRecordDTO pageRecordDTO) {
        PageRecordEntity pageRecordEntity = convertDtoToEntity(pageRecordDTO);
        Long count = recordMapper.countPageRecord(pageRecordEntity);
        if (count == null) {
            count = 0L;
            return new PageDTO<>(new ArrayList<>(), count);
        }
        List<String> fieldIdList = new ArrayList();
        if (!ObjectUtils.isEmpty(pageRecordEntity.getFieldId())) {
            fieldIdList.add(pageRecordEntity.getFieldId());
        } else if (!CollectionUtils.isEmpty(pageRecordDTO.getFieldIds())) {
            fieldIdList.addAll(pageRecordEntity.getFieldIds());
        }
        pageRecordEntity.setFieldIds(fieldIdList);

        PageParam pageParam = pageRecordEntity.getPageParam();
        if (pageParam != null) {
            if (Objects.isNull(pageParam.getPage())) {
                pageParam.setPage(0);
            }
            if (pageParam.getPage() < 0) {
                pageParam.setPage(0);
            }
            pageRecordEntity.setStart(pageParam.getPage() * pageParam.getSize());
            pageRecordEntity.setSize(Optional.ofNullable(pageParam.getSize()).orElse(10));
        }

        List<TxtanlRecordEntity> list = recordMapper.selectPageRecord(pageRecordEntity);
        List<RecordDO> doList = new ArrayList<>();
        for (TxtanlRecordEntity entity : list) {
            if (entity != null) {
                RecordDO recordDO = entityToDo(entity);
                doList.add(recordDO);
            }
        }
        return new PageDTO<>(doList, count);
    }

    /**
     * 根据项目id获取一条原话记录
     *
     * @param projectId 项目id
     * @return 记录
     */
    @Override
    public RecordDO getRecordByProjectId(String projectId) {
        TxtanlRecordEntity entity = recordMapper.getRecordByProjectId(projectId);
        if (entity == null) {
            return null;
        }
        return entityToDo(entity);
    }

    /**
     * 删除分析项目下的全部话题
     *
     * @param projectId 项目id
     * @return 条数
     */
    @Override
    public boolean deleteProjectAllRecord(String projectId) {
        return recordMapper.deleteProjectAllRecord(projectId) > Constants.INT_ZERO;
    }

    /**
     * 查询项目下所有原话的数量
     *
     * @param projectId 项目id
     * @return 数量
     */
    @Override
    public long countProjectAllRecord(String projectId) {
        Long count = recordMapper.countProjectAllRecord(projectId);
        if (count != null) {
            return count;
        }
        return 0;
    }

    /**
     * 查询项目对应字段下所有原话的数量
     *
     * @param projectId 项目id
     * @param fieldId   fieldId
     * @return 数量
     */
    @Override
    public long countProjectFieldRecord(String projectId, String fieldId) {
        Long count = recordMapper.countProjectFieldRecord(projectId, fieldId);
        if (count != null) {
            return count;
        }
        return 0;
    }

    /**
     * 查询项目对应字段原话记录的最大 collection_time
     *
     * @param projectId 项目id
     * @param fieldId   字段id
     * @return 时间字符串
     */
    @Override
    public String findMaxCollectionTime(String projectId, String fieldId) {
        Date date = recordMapper.findMaxCollectionTime(projectId, fieldId);
        if (date != null) {
            return date.toString();
        }
        return "";
    }

    /**
     * 查询项目对应字段原话记录的最大 创建时间
     *
     * @param projectId 项目id
     * @param fieldId   字段id
     * @return 时间字符串
     */
    @Override
    public String findMaxCreatedDt(String projectId, String fieldId) {
        Date date = recordMapper.findMaxCreatedDt(projectId, fieldId);
        if (date != null) {
            return date.toString();
        }
        return "";
    }

    @Override
    public List<RecordDO> listRecordByProjectId(String oldProjectId) {
        List<TxtanlRecordEntity> entities = recordMapper.listRecordByProjectId(oldProjectId);
        List<RecordDO> recordDOS = listToDoList(entities);
        return recordDOS;
    }

    /**
     * DTO 转 Entity
     *
     * @param pageRecordDTO
     * @return com.bestcem.xm.txtanls.entity.mysql.PageRecordEntity
     * @author cuiqiongyu <qiongyu.cui@idiaoyan.cn>
     * @date 2021/10/09 13:34
     */
    private PageRecordEntity convertDtoToEntity(PageRecordDTO pageRecordDTO) {
        PageRecordEntity pageRecordEntity = new PageRecordEntity();
        if (null == pageRecordDTO) {
            return pageRecordEntity;
        }
        pageRecordEntity = BeanUtil.copyProperties(pageRecordDTO, PageRecordEntity.class);
        return pageRecordEntity;
    }

}
